import express from 'express';
import { exec } from 'child_process';
import { promisify } from 'util';
import path from 'path';
import fs from 'fs';
import { v4 as uuidv4 } from 'uuid';
import { DatabaseProjectService } from '../services/DatabaseProjectService.js';
import { PathMappingService } from '../services/PathMappingService.js';

const router = express.Router();
const execAsync = promisify(exec);

// 数据模型接口定义
interface ProjectInfo {
  id: string;
  name: string;
  path: string;
  description?: string;
  lastAnalyzed?: Date;
  totalCommits?: number;
  authors?: string[];
  createdAt: Date;
  updatedAt: Date;
}

interface GitCommit {
  hash: string;
  author: string;
  email: string;
  date: Date;
  message: string;
  files: FileChange[];
  additions: number;
  deletions: number;
}

interface FileChange {
  file: string;
  type: 'added' | 'modified' | 'deleted' | 'renamed';
  additions: number;
  deletions: number;
  oldPath?: string; // for renamed files
}

// 使用数据库存储项目信息

/**
 * 添加项目
 * POST /api/git/projects
 */
router.post('/projects', async (req, res) => {
  try {
    const { name, path: projectPath, description } = req.body;

    if (!name || !projectPath) {
      return res.status(400).json({ 
        success: false, 
        error: '项目名称和路径不能为空' 
      });
    }

    // Docker环境路径映射
    const mappedPath = PathMappingService.mapHostPathToContainer(projectPath);
    console.log(`[Git] 原始路径: ${projectPath}, 映射路径: ${mappedPath}`);
    
    // 验证项目路径是否存在且为Git仓库
    const gitDir = path.join(mappedPath, '.git');
    if (!fs.existsSync(gitDir)) {
      return res.status(400).json({ 
        success: false, 
        error: `指定路径不是有效的Git仓库: ${mappedPath}` 
      });
    }

    // 检查项目是否已存在
    const existingProjects = await DatabaseProjectService.getAllProjects();
    const existingProject = existingProjects.find(p => p.path === projectPath);
    if (existingProject) {
      return res.status(400).json({ 
        success: false, 
        error: '项目已存在' 
      });
    }

    // 创建新项目（存储原始路径）
    const project = await DatabaseProjectService.addProject({
      name,
      path: projectPath, // 存储原始宿主机路径
      description: description || ''
    });

    res.json({ 
      success: true, 
      data: project 
    });
  } catch (error: any) {
    console.error('添加项目错误:', error);
    res.status(500).json({ 
      success: false, 
      error: `添加项目失败: ${error.message}` 
    });
  }
});

/**
 * 获取项目列表
 * GET /api/git/projects
 */
router.get('/projects', async (req, res) => {
  try {
    // 添加缓存控制头
    res.set({
      'Cache-Control': 'no-cache, no-store, must-revalidate',
      'Pragma': 'no-cache',
      'Expires': '0'
    });
    
    const projects = await DatabaseProjectService.getAllProjects();
    res.json({ 
      success: true, 
      data: projects 
    });
  } catch (error: any) {
    res.status(500).json({ 
      success: false, 
      error: `获取项目列表失败: ${error.message}` 
    });
  }
});

/**
 * 删除项目
 * DELETE /api/git/projects/:id
 */
router.delete('/projects/:id', async (req, res) => {
  try {
    const { id } = req.params;
    
    const projects = await DatabaseProjectService.getAllProjects();
    const project = projects.find(p => p.id === id);
    if (!project) {
      return res.status(404).json({ 
        success: false, 
        error: '项目不存在' 
      });
    }

    await DatabaseProjectService.deleteProject(id);

    res.json({ 
      success: true, 
      message: '项目删除成功' 
    });
  } catch (error: any) {
    res.status(500).json({ 
      success: false, 
      error: `删除项目失败: ${error.message}` 
    });
  }
});

/**
 * 获取Git提交记录
 * GET /api/git/commits
 */
router.get('/commits', async (req, res) => {
  try {
    const { projectPath, since, until, author, includeDiff } = req.query;

    if (!projectPath) {
      return res.status(400).json({ 
        success: false, 
        error: '项目路径不能为空' 
      });
    }

    // Docker环境路径映射
    const mappedPath = PathMappingService.mapHostPathToContainer(projectPath as string);
    console.log(`[Git Commits] 原始路径: ${projectPath}, 映射路径: ${mappedPath}`);
    
    // 验证项目路径是否存在且为Git仓库
    const gitDir = path.join(mappedPath, '.git');
    if (!fs.existsSync(gitDir)) {
      return res.status(400).json({ 
        success: false, 
        error: `指定路径不是有效的Git仓库: ${mappedPath}` 
      });
    }

    // 首先检查是否有提交记录
    try {
      const { stdout: hasCommits } = await execAsync('git rev-list --count --all', {
        cwd: mappedPath
      });
      
      if (parseInt(hasCommits.trim()) === 0) {
        return res.json({ 
          success: true, 
          commits: [], 
          total: 0,
          message: '仓库暂无提交记录'
        });
      }
    } catch (error) {
      return res.json({ 
        success: true, 
        commits: [], 
        total: 0,
        message: '仓库暂无提交记录'
      });
    }

    // 构建Git命令
    let gitLogCommand;
    if (includeDiff === 'true') {
      // 使用与parseGitLog兼容的格式，限制提交数量以避免超时
      gitLogCommand = 'git log --pretty=format:"%H|%s|%an|%ad" --date=iso --numstat -50';
    } else {
      // 使用与parseGitCommits兼容的格式 - 修复格式匹配问题
      gitLogCommand = 'git log --pretty=format:"%H|%an|%ae|%ad|%s" --date=iso --numstat';
    }
    
    if (since) {
      // 保持完整的ISO时间格式，Git可以正确解析
      gitLogCommand += ` --since="${since}"`;
    }
    
    if (until) {
      // 保持完整的ISO时间格式，Git可以正确解析
      gitLogCommand += ` --until="${until}"`;
    }
    
    if (author) {
      const authors = Array.isArray(author) ? author : [author];
      for (const a of authors) {
        gitLogCommand += ` --author="${a}"`;
      }
    }
    
    // 添加调试日志
    console.log('执行Git命令:', gitLogCommand);
    console.log('作者过滤参数:', author);

    const { stdout } = await execAsync(gitLogCommand, {
      cwd: mappedPath,
      maxBuffer: 1024 * 1024 * 10 // 10MB buffer
    });

    if (!stdout.trim()) {
      return res.json({ 
        success: true, 
        commits: [], 
        total: 0 
      });
    }

    // 根据includeDiff参数决定返回格式
    if (includeDiff === 'true') {
      // 使用parseGitLog解析（与analyze端点一致）
      let commits = parseGitLog(stdout);
      
      // 如果有作者过滤参数，在解析后再次过滤
      if (author) {
        const authors = Array.isArray(author) ? author.map(a => String(a)) : [String(author)];
        commits = commits.filter(commit => 
          authors.some(a => 
            commit.author.toLowerCase().includes(a.toLowerCase()) ||
            a.toLowerCase().includes(commit.author.toLowerCase())
          )
        );
      }
      
      // 转换为包含diff内容的GitChange格式
      const changes = await convertToGitChanges(commits, projectPath as string);
      
      res.json({ 
        success: true, 
        commits: changes, 
        total: changes.length 
      });
    } else {
      // 使用原有的parseGitCommits解析，返回GitCommit格式
      let commits = parseGitCommits(stdout);
      
      // 如果有作者过滤参数，在解析后再次过滤
      if (author) {
        const authors = Array.isArray(author) ? author.map(a => String(a)) : [String(author)];
        commits = commits.filter(commit => 
          authors.some(a => 
            commit.author.toLowerCase().includes(a.toLowerCase()) ||
            a.toLowerCase().includes(commit.author.toLowerCase())
          )
        );
      }
      
      res.json({ 
        success: true, 
        commits, 
        total: commits.length 
      });
    }
  } catch (error: any) {
    console.error('获取Git提交记录错误:', error);
    res.status(500).json({ 
      success: false, 
      error: `获取Git提交记录失败: ${error.message}` 
    });
  }
});

/**
 * 根据哈希获取Git提交记录
 * POST /api/git/commits/by-hashes
 */
router.post('/commits/by-hashes', async (req, res) => {
  try {
    const { projectPath, hashes, includeDiff } = req.body;

    if (!projectPath) {
      return res.status(400).json({ 
        success: false, 
        error: '项目路径不能为空' 
      });
    }

    if (!hashes || !Array.isArray(hashes) || hashes.length === 0) {
      return res.status(400).json({ 
        success: false, 
        error: '提交哈希列表不能为空' 
      });
    }

    // Docker环境路径映射
    const mappedPath = PathMappingService.mapHostPathToContainer(projectPath as string);
    console.log(`[Git Commits By Hashes] 原始路径: ${projectPath}, 映射路径: ${mappedPath}`);
    
    // 验证项目路径是否存在且为Git仓库
    const gitDir = path.join(mappedPath, '.git');
    if (!fs.existsSync(gitDir)) {
      return res.status(400).json({ 
        success: false, 
        error: `指定路径不是有效的Git仓库: ${mappedPath}` 
      });
    }

    // 构建Git命令，根据哈希获取提交记录
    // 使用git show命令来获取特定的commit hash，而不是git log
    let gitCommands: string[] = [];
    
    if (includeDiff === 'true') {
      // 使用与parseGitLog兼容的格式
      gitCommands = hashes.map(hash => 
        `git show --pretty=format:"%H|%s|%an|%ad" --date=iso --numstat ${hash}`
      );
    } else {
      // 使用与parseGitCommits兼容的格式
      gitCommands = hashes.map(hash => 
        `git show --pretty=format:"%H|%an|%ae|%ad|%s" --date=iso --numstat ${hash}`
      );
    }
    
    console.log('执行Git命令数量:', gitCommands.length);

    // 执行所有git show命令并合并结果
    let allOutput = '';
    for (const gitCommand of gitCommands) {
      try {
        console.log('执行Git命令:', gitCommand);
        const { stdout } = await execAsync(gitCommand, {
          cwd: mappedPath,
          maxBuffer: 1024 * 1024 * 10 // 10MB buffer
        });
        if (stdout.trim()) {
          allOutput += stdout + '\n';
        }
      } catch (error) {
        console.warn(`执行命令失败: ${gitCommand}`, error);
        // 继续执行其他命令，不中断整个流程
      }
    }

    if (!allOutput.trim()) {
      return res.json({ 
        success: true, 
        commits: [], 
        total: 0 
      });
    }

    // 根据includeDiff参数决定返回格式
    if (includeDiff === 'true') {
      // 使用parseGitLog解析（与analyze端点一致）
      const commits = parseGitLog(allOutput);
      
      // 转换为包含diff内容的GitChange格式，传递原始路径让convertToGitChanges内部处理映射
      const changes = await convertToGitChanges(commits, projectPath as string);
      
      res.json({ 
        success: true, 
        commits: changes, 
        total: changes.length 
      });
    } else {
      // 使用原有的parseGitCommits解析，返回GitCommit格式
      const commits = parseGitCommits(allOutput);
      
      res.json({ 
        success: true, 
        commits, 
        total: commits.length 
      });
    }
  } catch (error: any) {
    console.error('根据哈希获取Git提交记录错误:', error);
    res.status(500).json({ 
      success: false, 
      error: `根据哈希获取Git提交记录失败: ${error.message}` 
    });
  }
});

/**
 * 分析Git仓库变更记录
 */
router.post('/analyze', async (req, res) => {
  try {
    const { projectPath, startDate, endDate, excludePatterns = [] } = req.body;

    if (!projectPath) {
      return res.status(400).json({ error: '项目路径不能为空' });
    }

    // Docker环境路径映射
    const mappedPath = PathMappingService.mapHostPathToContainer(projectPath);
    console.log(`[Git Stats] 原始路径: ${projectPath}, 映射路径: ${mappedPath}`);
    
    // 验证项目路径是否存在且为Git仓库
    const gitDir = path.join(mappedPath, '.git');
    if (!fs.existsSync(gitDir)) {
      return res.status(400).json({ error: `指定路径不是有效的Git仓库: ${mappedPath}` });
    }

    // 首先检查是否有提交记录
    try {
      const { stdout: hasCommits } = await execAsync('git rev-list --count --all', {
        cwd: mappedPath
      });
      
      if (parseInt(hasCommits.trim()) === 0) {
        return res.json({ 
          success: true, 
          data: [],
          message: '仓库暂无提交记录'
        });
      }
    } catch (error) {
      return res.json({ 
        success: true, 
        data: [],
        message: '仓库暂无提交记录'
      });
    }

    // 构建Git命令
    const sinceDate = startDate ? `--since="${startDate}"` : '';
    const untilDate = endDate ? `--until="${endDate}"` : '';
    
    // 获取提交记录
    const gitLogCommand = `git log ${sinceDate} ${untilDate} --pretty=format:"%H|%s|%an|%ad" --date=iso --numstat`;
    
    const { stdout } = await execAsync(gitLogCommand, {
      cwd: mappedPath,
      maxBuffer: 1024 * 1024 * 10 // 10MB buffer
    });

    if (!stdout.trim()) {
      return res.json({ success: true, data: [] });
    }

    // 解析Git日志输出
    const commits = parseGitLog(stdout);
    
    // 应用排除模式过滤
    const filteredCommits = applyExcludePatterns(commits, excludePatterns);
    
    // 转换为前端需要的格式
    const changes = await convertToGitChanges(filteredCommits, projectPath);

    res.json({ success: true, data: changes });
  } catch (error: any) {
    console.error('Git分析错误:', error);
    res.status(500).json({ 
      success: false, 
      error: `Git分析失败: ${error.message}` 
    });
  }
});

/**
 * 获取单个提交的diff内容
 */
async function getCommitDiff(projectPath: string, commitHash: string): Promise<string> {
  try {
    console.log(`[getCommitDiff] 开始获取提交 ${commitHash} 的diff，项目路径: ${projectPath}`);
    
    // 获取diff格式的内容，使用git diff命令获取真正的diff
    const result = await execAsync(`git diff ${commitHash}~1 ${commitHash}`, {
      cwd: projectPath,
      maxBuffer: 1024 * 1024 * 10 // 10MB buffer
    });
    
    console.log(`[getCommitDiff] execAsync结果:`, {
      stdout_length: result.stdout?.length || 0,
      stderr_length: result.stderr?.length || 0,
      stderr_content: result.stderr || 'no stderr'
    });
    
    const diffOutput = result.stdout || '';
    console.log(`[getCommitDiff] 准备返回diff，内容长度: ${diffOutput.length}`);
    
    if (diffOutput.length > 0) {
      console.log(`[getCommitDiff] diff内容预览: ${diffOutput.substring(0, 200)}...`);
      console.log(`[getCommitDiff] 成功返回提交 ${commitHash} 的diff`);
      return diffOutput;
    } else {
      console.log(`[getCommitDiff] 警告: diff内容为空，返回空字符串`);
      return '';
    }
  } catch (error) {
    console.error(`[getCommitDiff] 获取提交${commitHash}的diff失败:`, error);
    return '';
  }
}

/**
 * 解析Git日志输出
 */
function parseGitLog(output: string): GitCommit[] {
  const commits: GitCommit[] = [];
  const lines = output.split('\n');
  let currentCommit: Partial<GitCommit> | null = null;

  for (const line of lines) {
    if (line.includes('|') && line.split('|').length === 4) {
      // 新的提交记录
      if (currentCommit) {
        commits.push(currentCommit as GitCommit);
      }
      
      const [hash, message, author, date] = line.split('|');
      currentCommit = {
        hash,
        message,
        author,
        date: new Date(date),
        files: []
      };
    } else if (line.trim() && currentCommit && line.includes('\t')) {
      // 文件变更统计
      const parts = line.split('\t');
      if (parts.length >= 3) {
        const additions = parseInt(parts[0]) || 0;
        const deletions = parseInt(parts[1]) || 0;
        const filename = parts[2];
        
        let type: 'added' | 'modified' | 'deleted' = 'modified';
        if (additions > 0 && deletions === 0) {
          type = 'added';
        } else if (additions === 0 && deletions > 0) {
          type = 'deleted';
        }
        
        currentCommit.files!.push({
          file: filename,
          type,
          additions,
          deletions
        });
      }
    }
  }
  
  // 添加最后一个提交
  if (currentCommit) {
    commits.push(currentCommit as GitCommit);
  }
  
  return commits;
}

/**
 * 应用排除模式过滤
 */
function applyExcludePatterns(commits: GitCommit[], excludePatterns: string[]): GitCommit[] {
  if (excludePatterns.length === 0) {
    return commits;
  }
  
  return commits.map(commit => ({
    ...commit,
    files: commit.files.filter(file => {
      return !excludePatterns.some(pattern => {
        const regex = new RegExp(pattern.replace(/\*/g, '.*').replace(/\?/g, '.'));
        return regex.test(file.file);
      });
    })
  })).filter(commit => commit.files.length > 0);
}

/**
 * 转换为前端需要的GitChange格式（带diff内容）
 */
async function convertToGitChanges(commits: GitCommit[], projectPath: string): Promise<any[]> {
  const changes: any[] = [];
  
  // Docker环境路径映射
  const mappedPath = PathMappingService.mapHostPathToContainer(projectPath);
  console.log(`[convertToGitChanges] 原始路径: ${projectPath}, 映射路径: ${mappedPath}`);
  
  for (const commit of commits) {
    // 获取该提交的完整diff内容，使用映射后的路径
    const fullDiff = await getCommitDiff(mappedPath, commit.hash);
    console.log(`[convertToGitChanges] 获取提交 ${commit.hash} 的diff，长度: ${fullDiff.length}`);
    
    for (const file of commit.files) {
      // 从完整diff中提取该文件的diff部分
      const fileDiff = extractFileDiffFromFullDiff(fullDiff, file.file);
      console.log(`[convertToGitChanges] 文件 ${file.file} 的diff长度: ${fileDiff.length}`);
      
      changes.push({
        file: file.file,
        type: file.type,
        additions: file.additions,
        deletions: file.deletions,
        diff: fileDiff, // 现在包含真实的diff内容
        commit: {
          hash: commit.hash,
          message: commit.message,
          author: commit.author,
          date: commit.date
        }
      });
    }
  }
  
  return changes;
}

/**
 * 从完整的diff输出中提取特定文件的diff内容
 */
function extractFileDiffFromFullDiff(fullDiff: string, filename: string): string {
  console.log(`[extractFileDiff] 提取文件 ${filename} 的diff，完整diff长度: ${fullDiff.length}`);
  
  if (!fullDiff || !filename) {
    console.log(`[extractFileDiff] 参数无效: fullDiff长度=${fullDiff?.length || 0}, filename=${filename}`);
    return '';
  }
  
  const lines = fullDiff.split('\n');
  const fileDiffLines: string[] = [];
  let inTargetFile = false;
  let foundFile = false;
  
  // 清理文件名，移除引号
  const cleanFilename = filename.replace(/^"|"$/g, '');
  console.log(`[extractFileDiff] 清理后的文件名: ${cleanFilename}`);
  
  for (let i = 0; i < lines.length; i++) {
    const line = lines[i];
    
    // 检查是否是文件头 - 更精确的匹配
    if (line.startsWith('diff --git')) {
      // 提取diff行中的文件路径
      const diffMatch = line.match(/diff --git a\/(.*?) b\/(.*?)$/);
      if (diffMatch) {
        const [, oldPath, newPath] = diffMatch;
        // 检查是否匹配目标文件（支持新文件和旧文件路径）
        if (oldPath === cleanFilename || newPath === cleanFilename || 
            oldPath.endsWith(cleanFilename) || newPath.endsWith(cleanFilename)) {
          console.log(`[extractFileDiff] 找到文件 ${cleanFilename} 的diff头: ${line}`);
          console.log(`[extractFileDiff] 匹配路径: oldPath=${oldPath}, newPath=${newPath}`);
          inTargetFile = true;
          foundFile = true;
          fileDiffLines.push(line);
          continue;
        }
      }
      
      // 如果遇到新的文件diff且当前在目标文件中，停止收集
      if (inTargetFile) {
        console.log(`[extractFileDiff] 遇到新文件diff，停止收集: ${line}`);
        break;
      }
    }
    
    // 收集目标文件的diff行
    if (inTargetFile) {
      fileDiffLines.push(line);
    }
  }
  
  const result = foundFile ? fileDiffLines.join('\n') : '';
  console.log(`[extractFileDiff] 文件 ${cleanFilename} 提取结果: 找到=${foundFile}, diff长度=${result.length}`);
  
  if (foundFile && result.length > 0) {
    console.log(`[extractFileDiff] diff内容预览: ${result.substring(0, 300)}...`);
  }
  
  return result;
}

/**
 * 获取完整的Git提交日志
 */
router.post('/log', async (req, res) => {
  try {
    const { projectPath, format = 'full', maxCount = 100, author, since, until } = req.body;

    if (!projectPath) {
      return res.status(400).json({ error: '项目路径不能为空' });
    }

    // Docker环境路径映射
    const mappedPath = PathMappingService.mapHostPathToContainer(projectPath);
    console.log(`[Git Log] 原始路径: ${projectPath}, 映射路径: ${mappedPath}`);
    
    // 验证项目路径是否存在且为Git仓库
    const gitDir = path.join(mappedPath, '.git');
    if (!fs.existsSync(gitDir)) {
      return res.status(400).json({ error: `指定路径不是有效的Git仓库: ${mappedPath}` });
    }

    // 构建Git log命令
    let gitLogCommand = 'git log';
    
    // 添加格式参数
    if (format === 'full') {
      gitLogCommand += ' --pretty=fuller';
    } else if (format === 'oneline') {
      gitLogCommand += ' --oneline';
    } else {
      gitLogCommand += ' --pretty=format:"%H|%s|%an|%ae|%ad" --date=iso';
    }
    
    // 添加限制条件
    if (maxCount) {
      gitLogCommand += ` -n ${maxCount}`;
    }
    
    if (author) {
      gitLogCommand += ` --author="${author}"`;
    }
    
    if (since) {
      gitLogCommand += ` --since="${since}"`;
    }
    
    if (until) {
      gitLogCommand += ` --until="${until}"`;
    }
    
    // 首先检查是否有提交记录
    try {
      const { stdout: hasCommits } = await execAsync('git rev-list --count --all', {
        cwd: mappedPath
      });
      
      if (parseInt(hasCommits.trim()) === 0) {
        return res.json({ 
          success: true, 
          data: '',
          message: '仓库暂无提交记录',
          command: gitLogCommand
        });
      }
    } catch (error) {
      return res.json({ 
        success: true, 
        data: '',
        message: '仓库暂无提交记录',
        command: gitLogCommand
      });
    }

    // 添加所有分支
    gitLogCommand += ' --all';
    
    console.log(`执行Git命令: ${gitLogCommand}`);
    
    const { stdout } = await execAsync(gitLogCommand, {
      cwd: mappedPath,
      maxBuffer: 1024 * 1024 * 10 // 10MB buffer
    });

    if (!stdout.trim()) {
      return res.json({ success: true, data: '' });
    }

    console.log(`Git log输出长度: ${stdout.length} 字符`);
    
    res.json({ 
      success: true, 
      data: stdout,
      command: gitLogCommand
    });
  } catch (error: any) {
    console.error('Git log错误:', error);
    res.status(500).json({ 
      success: false, 
      error: `Git log失败: ${error.message}` 
    });
  }
});

/**
 * 获取项目作者列表
 * GET /api/git/projects/authors
 */
router.get('/projects/authors', async (req, res) => {
  try {
    const { projectPath } = req.query;

    if (!projectPath) {
      return res.status(400).json({ 
        success: false, 
        error: '项目路径不能为空' 
      });
    }

    // Docker环境路径映射
    const mappedPath = PathMappingService.mapHostPathToContainer(projectPath as string);
    console.log(`[Git Authors] 原始路径: ${projectPath}, 映射路径: ${mappedPath}`);
    
    // 验证项目路径是否存在且为Git仓库
    const gitDir = path.join(mappedPath, '.git');
    if (!fs.existsSync(gitDir)) {
      return res.status(400).json({ 
        success: false, 
        error: `指定路径不是有效的Git仓库: ${mappedPath}` 
      });
    }

    const authors = await getProjectAuthors(mappedPath);
    
    res.json({ 
      success: true, 
      data: authors 
    });
  } catch (error: any) {
    console.error('获取项目作者失败:', error);
    res.status(500).json({ 
      success: false, 
      error: `获取项目作者失败: ${error.message}` 
    });
  }
});

/**
 * 获取Git仓库信息
 */
router.post('/info', async (req, res) => {
  try {
    const { projectPath } = req.body;

    if (!projectPath) {
      return res.status(400).json({ error: '项目路径不能为空' });
    }

    // Docker环境路径映射
    const mappedPath = PathMappingService.mapHostPathToContainer(projectPath);
    console.log(`[Git Info] 原始路径: ${projectPath}, 映射路径: ${mappedPath}`);
    
    // 验证是否为Git仓库
    const gitDir = path.join(mappedPath, '.git');
    if (!fs.existsSync(gitDir)) {
      return res.status(400).json({ error: `指定路径不是有效的Git仓库: ${mappedPath}` });
    }

    // 获取当前分支
    const { stdout: branch } = await execAsync('git branch --show-current', {
      cwd: mappedPath
    });

    // 获取远程URL
    let remoteUrl = '';
    try {
      const { stdout: remote } = await execAsync('git remote get-url origin', {
        cwd: mappedPath
      });
      remoteUrl = remote.trim();
    } catch {
      // 忽略没有远程仓库的情况
    }

    res.json({
      success: true,
      data: {
        branch: branch.trim(),
        remoteUrl,
        isGitRepo: true
      }
    });
  } catch (error: any) {
    console.error('获取Git信息错误:', error);
    res.status(500).json({ 
      success: false, 
      error: `获取Git信息失败: ${error.message}` 
    });
  }
});

// 辅助函数

/**
 * 获取项目作者列表
 */
async function getProjectAuthors(projectPath: string): Promise<string[]> {
  try {
    // 首先检查是否有提交记录
    const { stdout: hasCommits } = await execAsync('git rev-list --count --all', {
      cwd: projectPath
    });
    
    if (parseInt(hasCommits.trim()) === 0) {
      return [];
    }
    
    // 使用Windows兼容的命令获取作者列表
    const { stdout } = await execAsync('git log --format="%an"', {
      cwd: projectPath,
      maxBuffer: 1024 * 1024
    });
    
    // 手动去重和排序，替代uniq命令
    const authors = stdout.trim().split('\n')
      .filter(author => author.trim())
      .filter((author, index, arr) => arr.indexOf(author) === index) // 去重
      .sort(); // 排序
    
    return authors;
  } catch (error) {
    console.error('获取项目作者失败:', error);
    return [];
  }
}

/**
 * 获取项目总提交数
 */
async function getTotalCommits(projectPath: string): Promise<number> {
  try {
    // 首先检查是否有提交记录
    const { stdout } = await execAsync('git rev-list --count --all', {
      cwd: projectPath
    });
    return parseInt(stdout.trim()) || 0;
  } catch (error) {
    console.error('获取提交数失败:', error);
    // 如果命令失败，可能是空仓库，返回0
    return 0;
  }
}

/**
 * 解析Git提交记录
 */
function parseGitCommits(output: string): GitCommit[] {
  const commits: GitCommit[] = [];
  const lines = output.split('\n');
  let currentCommit: Partial<GitCommit> | null = null;

  for (const line of lines) {
    if (line.includes('|') && line.split('|').length === 5) {
      // 新的提交记录
      if (currentCommit) {
        // 计算总的添加和删除行数
        currentCommit.additions = currentCommit.files?.reduce((sum, file) => sum + file.additions, 0) || 0;
        currentCommit.deletions = currentCommit.files?.reduce((sum, file) => sum + file.deletions, 0) || 0;
        commits.push(currentCommit as GitCommit);
      }
      
      const [hash, author, email, date, message] = line.split('|');
      currentCommit = {
        hash,
        author,
        email,
        date: new Date(date),
        message,
        files: [],
        additions: 0,
        deletions: 0
      };
    } else if (line.trim() && currentCommit && line.includes('\t')) {
      // 文件变更统计
      const parts = line.split('\t');
      if (parts.length >= 3) {
        const additions = parseInt(parts[0]) || 0;
        const deletions = parseInt(parts[1]) || 0;
        const filename = parts[2];
        
        let status: 'added' | 'modified' | 'deleted' | 'renamed' = 'modified';
        if (additions > 0 && deletions === 0) {
          status = 'added';
        } else if (additions === 0 && deletions > 0) {
          status = 'deleted';
        } else if (filename.includes(' => ')) {
          status = 'renamed';
        }
        
        const fileChange: FileChange = {
          file: filename,
          type: status,
          additions,
          deletions
        };
        
        // 处理重命名文件
        if (status === 'renamed' && filename.includes(' => ')) {
          const [oldPath, newPath] = filename.split(' => ');
          fileChange.oldPath = oldPath.trim();
          fileChange.file = newPath.trim();
        }
        
        currentCommit.files!.push(fileChange);
      }
    }
  }
  
  // 添加最后一个提交
  if (currentCommit) {
    currentCommit.additions = currentCommit.files?.reduce((sum, file) => sum + file.additions, 0) || 0;
    currentCommit.deletions = currentCommit.files?.reduce((sum, file) => sum + file.deletions, 0) || 0;
    commits.push(currentCommit as GitCommit);
  }
  
  return commits;
}

export default router;